﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Reflection;

namespace Player
{
    [AttributeUsage(AttributeTargets.Field)]
    public class InputMappingAttribute : Attribute
    {
        private int m_variable;

        public InputMappingAttribute(int variable)
        {
            m_variable = variable;
        }

        public int Variable
        {
            get { return m_variable; }
        }
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class OutputMappingAttribute : Attribute
    {
        private int m_variable;
        private SqlDbType m_dbType;
        private int m_size;

        public OutputMappingAttribute(int variable, SqlDbType dbType)
        {
            m_variable = variable;
            m_dbType = dbType;
        }

        public OutputMappingAttribute(int variable, SqlDbType dbType, int size)
        {
            m_variable = variable;
            m_dbType = dbType;
            m_size = size;
        }

        public int Variable
        {
            get { return m_variable; }
        }

        public SqlDbType DbType
        {
            get { return m_dbType; }
        }

        public int Size
        {
            get { return m_size; }
        }
    }
    
    [AttributeUsage(AttributeTargets.Field)]
    public class ColumnMappingAttribute : Attribute
    {
        private Type m_table;
        private int m_column;

        public ColumnMappingAttribute()
        {
        }

        public ColumnMappingAttribute(Type table, int column)
        {
            m_table = table;
            m_column = column;
        }

        public string Name
        {
            get
            {
                string prefix = null;

                TableAttribute attr = Attribute.GetCustomAttribute(m_table, typeof(TableAttribute)) as TableAttribute;
                if (attr != null) prefix = attr.Name;

                ViewAttribute vattr = Attribute.GetCustomAttribute(m_table, typeof(ViewAttribute)) as ViewAttribute;
                if (vattr != null) prefix = vattr.Name;

                if (prefix == null) throw new Exception("Table name is not defined.  Please use TableAttribute to define the table name");

                foreach (FieldInfo fi in m_table.GetFields(BindingFlags.Public | BindingFlags.Static))
                {
                    if ((int)fi.GetRawConstantValue() == m_column)
                    {
                        return "[" + prefix + "].[" + fi.Name + "]";
                    }
                }

                throw new Exception("Unknown column mapped by ColumnMappingAttribute");
            }
        }
    }

    [AttributeUsage(AttributeTargets.Enum)]
    public class ViewAttribute : Attribute
    {
        private string m_name;
        private bool m_suppressCreation;

        public string Name
        {
            get { return m_name; }
        }

        public ViewAttribute(string name)
        {
            m_name = name;
        }

        public ViewAttribute(string name, bool suppressCreation)
        {
            m_name = name;
            m_suppressCreation = suppressCreation;
        }
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class ColumnAttribute : Attribute
    {
        private SqlDbType m_type;
        private int? m_maxLength;
        private bool m_isNullable;
        private bool m_isIdentity;
        private Type m_foreignTable;
        private int m_foreignKey;

        public ColumnAttribute(SqlDbType type)
            : this(type, false)
        {
            m_maxLength = null;
        }

        public ColumnAttribute(SqlDbType type, bool isNullable)
        {
            m_type = type;
            m_maxLength = null;
            m_isNullable = isNullable;
            m_isIdentity = false;
        }

        public ColumnAttribute(SqlDbType type, bool isNullable, bool isIdentity)
        {
            m_type = type;
            m_maxLength = null;
            m_isNullable = isNullable;
            m_isIdentity = isIdentity;
        }

        public ColumnAttribute(SqlDbType type, bool isNullable, bool isIdentity, Type foreignTable, int foreignKey)
            : this(type, isNullable, isIdentity)
        {
            m_foreignTable = foreignTable;
            m_foreignKey = foreignKey;
        }

        public ColumnAttribute(SqlDbType type, int maxLength)
            : this(type, maxLength, false)
        {
        }

        public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable)
        {
            m_type = type;
            m_maxLength = maxLength;
            m_isNullable = isNullable;
            m_isIdentity = false;
        }

        public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable, bool isIdentity)
        {
            m_type = type;
            m_maxLength = maxLength;
            m_isNullable = isNullable;
            m_isIdentity = isIdentity;
        }

        public ColumnAttribute(SqlDbType type, int maxLength, bool isNullable, bool isIdentity, Type foreignTable, int foreignKey)
            : this(type, maxLength, isNullable, isIdentity)
        {
            m_foreignTable = foreignTable;
            m_foreignKey = foreignKey;
        }

        public SqlDbType Type
        {
            get
            {
                return m_type;
            }
        }

        public int? MaxLength
        {
            get
            {
                return m_maxLength;
            }
        }

        public bool IsNullable
        {
            get
            {
                return m_isNullable;
            }
        }

        public bool IsIdentity
        {
            get
            {
                return m_isIdentity;
            }
        }

        public Type ForeignTable
        {
            get { return m_foreignTable; }
        }

        public int ForeignKey
        {
            get { return m_foreignKey; }
        }
    }

    [AttributeUsage(AttributeTargets.Enum)]
    public class TableAttribute : Attribute
    {
        private string m_name;
        private bool m_suppressCreation;

        public TableAttribute(string name)
        {
            m_name = name;
        }

        public TableAttribute(string name, bool suppressCreation)
        {
            m_name = name;
            m_suppressCreation = suppressCreation;
        }

        public string Name
        {
            get { return m_name; }
        }

        public bool SuppressCreation
        {
            get { return m_suppressCreation; }
        }
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class VariableAttribute : Attribute
    {
        private Direction m_direction;

        public VariableAttribute(Direction direction)
        {
            m_direction = direction;
        }

        public Direction Direction
        {
            get { return m_direction; }
        }
    }

    [AttributeUsage(AttributeTargets.Field)]
    public class PropertyAttribute : Attribute
    {
        private SqlDbType m_type;
        private int? m_maxLength;

        public PropertyAttribute(SqlDbType type)
        {
            m_type = type;
            m_maxLength = null;
        }

        public PropertyAttribute(SqlDbType type, int maxLength)
        {
            m_type = type;
            m_maxLength = maxLength;
        }

        public SqlDbType Type
        {
            get
            {
                return m_type;
            }
        }

        public int? MaxLength
        {
            get
            {
                return m_maxLength;
            }
        }
    }
}
